#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
/*
回调函数
_recver：当从对应的_sockfd接收到数据时，这个回调函数可能会被调用。它通常用于处理接收到的数据。
_sender：当需要向对应的_sockfd发送数据时，这个回调函数可能会被调用。它通常用于处理发送数据的逻辑。
_excepter：当在对应的_sockfd上发生异常或错误时，这个回调函数可能会被调用。它通常用于处理异常情况。

回指指针（TcpServer *_R）
用途：回指指针通常用于将一个对象（在这里    是TCP连接对象）与其所属的更大上下文（在这里是TcpServer对象）关联起来。
这使得TCP连接对象能够访问其父对象（TcpServer）的数据或方法。

为什么需要它：在许多情况下，一个TcpServer对象会管理多个TCP连接对象。
这些连接对象可能需要访问TcpServer的一些资源或方法，
例如用于发送数据到另一个客户端、获取服务器状态、触发全局事件等。通过回指指针，TCP连接对象可以轻松地访问其父对象TcpServer。

如何使用：在TcpServer中创建TCP连接对象时，可以将TcpServer的this指针作为回指指针传递给TCP连接对象。
这样，TCP连接对象就可以在其生命周期内随时访问TcpServer对象。
*/

class Connection;
class TcpServer;

using func_t = std::function<void(Connection *)>;

class Connection // 客户端的升级版,保存的是用户的相关操作，但用户不需要知道其内部实现的细节，只需调用接口即可
{
public:
    Connection(int sockfd, uint32_t events, TcpServer *R)
        : _sockfd(sockfd), _events(events), _R(R)
        {}

    void RegisterCallback(func_t recver, func_t sender, func_t excepter)
    {
        _recver = std::move(recver);
        _sender = std::move(sender);
        _excepter = std::move(excepter);
    }
    void AddInBuffer(std::string buffer)
    {
        _inbuffer += buffer; // 追加到inbuffer中
    }
    void AddOutBuffer(const std::string &buffer)
    {
        _outbuffer += buffer;
    }
    bool OutBufferEmpty()
    {
        return _outbuffer.empty();
    }
    int SockFd()
    {
        return _sockfd;
    }
    uint32_t Events()
    {
        return _events;
    }
    void SetEvents(uint32_t events)
    {
        _events = events;
    }
    void SetClient(const struct sockaddr_in c)
    {
        _client = c;
    }
    std::string &InBuffer()
    {
        return _inbuffer;
    }
    std::string &OutBuffer()
    {
        return _outbuffer;
    }
    void Close()
    {
        ::close(_sockfd);
    }
    ~Connection(){}

private:
    // 对应的sockfd
    int _sockfd;
    // 对应的缓冲区
    std::string _inbuffer;  // _sockfd 接受缓冲区, 暂时用string代替
    std::string _outbuffer; // _sockfd 发送缓冲区

    // 关心的事件
    uint32_t _events;
    // 维护一下client的ip和port信息
    struct sockaddr_in _client;

public:
    // 对特定connection进行处理的回调函数
    func_t _recver;
    func_t _sender;
    func_t _excepter;
    // Tcpserver的回指指针
    TcpServer *_R;
};


class ConnectionFactory
{
public:
    static Connection *BuildListenConnection(int listensock, func_t recver, uint32_t events, TcpServer *R)
    {
        Connection *conn = new Connection(listensock, events, R);
        conn->RegisterCallback(recver, nullptr, nullptr);
        return conn;
    }
    static Connection *BuildNormalConnection(int sockfd,
                                             auto recver,
                                             auto sender,
                                             auto excepter,
                                             uint32_t events,
                                             TcpServer *R)
    {
        Connection *conn = new Connection(sockfd, events, R);
        conn->RegisterCallback(recver, sender, excepter);
        return conn;
    }
};